package com.system.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 日期操作工具类
 *
 * @author huangyong
 * @since 1.0
 */
public class DateUtil {

    private static final Logger logger = LoggerFactory.getLogger(DateUtil.class);

    private static final SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    private static final SimpleDateFormat dateFormatMonth = new SimpleDateFormat("yyyy-MM");

    private static final SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
    private static final SimpleDateFormat dateMonthFormat = new SimpleDateFormat("_yyyy_M");
    public static final SimpleDateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");

    public static final SimpleDateFormat dateFormatHour = new SimpleDateFormat("yyyy-MM-dd HH");


    /**
     * 格式化日期与时间
     */
    public static String formatDatetime(long timestamp) {
        return datetimeFormat.format(new Date(timestamp));
    }

    /**
     * 格式化日期
     */
    public static String formatDate(long timestamp) {
        return dateFormat.format(new Date(timestamp));
    }

    /**
     * 格式化时间
     */
    public static String formatTime(long timestamp) {
        return timeFormat.format(new Date(timestamp));
    }

    /**
     * 返回_YYYY_MM格式
     *
     * @param timestamp
     * @return
     */
    public static String formatMonth(long timestamp) {
        return dateMonthFormat.format(new Date(timestamp));
    }

    public static String formatMonth(String monthDateString) {
        return dateMonthFormat.format(parseDate(monthDateString));
    }

    public static String formatMonthChange(String monthDateString) {
        Date date = parseDate(monthDateString);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return "_" + monthDateString.substring(0, 4) + "_" + (calendar.get(Calendar.MONTH) + 1);
    }

    /**
     * 获取当前日期与时间
     */
    public static String getCurrentDatetime() {
        return datetimeFormat.format(new Date());
    }

    /**
     * 获取当前日期
     */
    public static String getCurrentDate() {
        return dateFormat.format(new Date());
    }

    /**
     * 获取当前时间
     */
    public static String getCurrentTime() {
        return timeFormat.format(new Date());
    }

    /**
     * 解析日期与时间
     */
    public static Date parseDatetime(String str) {
        Date date = null;
        try {
            date = datetimeFormat.parse(str);
        } catch (ParseException e) {
            logger.error("解析日期字符串出错！格式：yyyy-MM-dd HH:mm:ss", e);
        }
        return date;
    }

    /**
     * 解析日期与时间
     */
    public static Date parseDatetime(String dateStr, SimpleDateFormat format) {
        Date date = null;
        try {
            date = format.parse(dateStr);
        } catch (ParseException e) {
            logger.error("解析日期字符串出错！", e);
        }
        return date;
    }

    /**
     * 解析日期
     */
    public static Date parseDate(String str) {
        Date date = null;
        try {
            date = dateFormat.parse(str);
        } catch (ParseException e) {
            logger.error("解析日期字符串出错！格式：yyyy-MM-dd", e);
        }
        return date;
    }

    /**
     * 解析时间
     */
    public static Date parseTime(String str) {
        Date date = null;
        try {
            date = timeFormat.parse(str);
        } catch (ParseException e) {
            logger.error("解析日期字符串出错！格式：HH:mm:ss", e);
        }
        return date;
    }

    public static List<String> getBetweenDays(String stime, String etime) {
        Date sdate = null;
        Date eDate = null;
        try {
            sdate = dateFormat.parse(stime);
            eDate = dateFormat.parse(etime);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Calendar c = Calendar.getInstance();
        List<String> list = new ArrayList<String>();
        if (null != sdate && null != eDate) {
            while (sdate.getTime() <= eDate.getTime()) {
                list.add(dateFormat.format(sdate));
                c.setTime(sdate);
                // 日期加1天
                c.add(Calendar.DATE, 1);
                sdate = c.getTime();
            }
        }
        return list;
    }

    public static void main(String[] args) {
        System.out.println(compare("2020-04-30","2020-05-30"));
    }

    public static boolean compare(String time1, String time2) {
        try {
            //如果想比较日期则写成"yyyy-MM-dd"就可以了
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            //将字符串形式的时间转化为Date类型的时间
            Date a = sdf.parse(time1);
            Date b = sdf.parse(time2);
            //Date类的一个方法，如果a早于b返回true，否则返回false
            if (a.before(b))
                return true;
            else
                return false;
		/*
		 * 如果你不喜欢用上面这个太流氓的方法，也可以根据将Date转换成毫秒
		if(a.getTime()-b.getTime()<0)
			return true;
		else
			return false;
		*/
        } catch (Exception e) {

        }
        return false;
    }

    /**
     * 计算日期相隔天数
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int daysBetween(Date date1, Date date2) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date1);
        long time1 = cal.getTimeInMillis();

        cal.setTime(date2);
        long time2 = cal.getTimeInMillis();

        long between_days = (time2 - time1) / (1000 * 3600 * 24);
        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 获取7天前日期
     *
     * @return
     */
    public static String dateJudge() {
        DateFormat dateMonth = new SimpleDateFormat("yyyy-MM");
        Date today = new Date();
        String dates = dateMonth.format(new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000));
        return dates;
    }

    /**
     * 指定日期增加指定天数
     *
     * @author 佛冷
     * @date 2019/12/30
     */
    public static Date getDateByDay(Date date, int day) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DAY_OF_MONTH, day);
        return c.getTime();
    }

    /**
     * 指定日期增加指定天数
     *
     * @Author 佛冷
     * @Date 2020/4/9 13:39
     */
    public static String getDateByDay(String dateStr, int day) {
        Date date = parseDate(dateStr);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DAY_OF_MONTH, day);
        return formatDate(c.getTime().getTime());
    }

    /**
     * 获得某天最大时间
     * yyyy-MM-dd 23:59:59
     *
     * @Author 佛冷
     * @Date 2020/1/17 13:21
     */
    public static String getEndOfDay(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
        LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);
        return formatDatetime(Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant()).getTime());
    }

    /**
     * 获得某天最小时间
     * yyyy-MM-dd 00:00:00
     *
     * @Author 佛冷
     * @Date 2020/1/17 13:21
     */
    public static String getStartOfDay(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
        LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);
        return formatDatetime(Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant()).getTime());
    }

    /**
     * 获取昨天日期
     *
     * @Author 佛冷
     * @Date 2020/1/17 13:25
     */
    public static Date getYesterday() {
        return getDateByDay(new Date(), -1);
    }


    /**
     * 获取两个日期相差的月数
     */
    public static int getMonthDiff(String startDate, String endDate) {
        Date d1 = parseDatetime(startDate, dateFormatMonth);
        Date d2 = parseDatetime(endDate, dateFormatMonth);
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(d1);
        c2.setTime(d2);
        int year1 = c1.get(Calendar.YEAR);
        int year2 = c2.get(Calendar.YEAR);
        int month1 = c1.get(Calendar.MONTH);
        int month2 = c2.get(Calendar.MONTH);
        int day1 = c1.get(Calendar.DAY_OF_MONTH);
        int day2 = c2.get(Calendar.DAY_OF_MONTH);
        // 获取年的差值 
        int yearInterval = year1 - year2;
        // 如果 d1的 月-日 小于 d2的 月-日 那么 yearInterval-- 这样就得到了相差的年数
        if (month1 < month2 || month1 == month2 && day1 < day2) {
            yearInterval--;
        }
        // 获取月数差值
        int monthInterval = (month1 + 12) - month2;
        if (day1 < day2) {
            monthInterval--;
        }
        monthInterval %= 12;
        int monthsDiff = Math.abs(yearInterval * 12 + monthInterval);
        return monthsDiff;
    }

    /**
     * 获取当前月份最后一天
     *
     * @Author 佛冷
     * @Date 2020/4/26 10:04
     */
    public static String getCurrentMonthLastDay() {
        // 获取Calendar
        Calendar calendar = Calendar.getInstance();
        // 设置日期为本月最权大日期
        calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
        return dateFormat.format(calendar.getTime());
    }

}
